package cn.xxstudy.blog.util

import org.commonmark.Extension
import org.commonmark.ext.gfm.tables.TableBlock
import org.commonmark.ext.gfm.tables.TablesExtension
import org.commonmark.ext.heading.anchor.HeadingAnchorExtension
import org.commonmark.node.Link
import org.commonmark.node.Node
import org.commonmark.parser.Parser
import org.commonmark.renderer.html.AttributeProvider
import org.commonmark.renderer.html.HtmlRenderer
import org.slf4j.LoggerFactory
import org.springframework.beans.BeanWrapper
import org.springframework.beans.BeanWrapperImpl
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.util.*


/**
 * 作者：wuxinxi on 2020/11/26
 * 包名：cn.xxstudy.blog.util
 * TODO:方法工具
 */

val logger = LoggerFactory.getLogger("logger")

/**
 *获取所有的属性值为空属性名数组
 */
fun getNullPropertyNames(source: Any): Array<String> {
    val beanWrapper: BeanWrapper = BeanWrapperImpl(source)
    val pds = beanWrapper.propertyDescriptors
    val nullPropertyNames: MutableList<String> = ArrayList()
    for (pd in pds) {
        val propertyName = pd.name
        if (beanWrapper.getPropertyValue(propertyName) == null) {
            nullPropertyNames.add(propertyName)
        }
    }
    return nullPropertyNames.toTypedArray()
}

fun markdownToHtml(markdown: String): String {
    val parser = Parser.builder().build()
    val document = parser.parse(markdown)
    val renderer = HtmlRenderer.builder().build()
    return renderer.render(document)
}


/**
 * 增加扩展[标题锚点，表格生成]
 * Markdown转换成HTML
 * @param markdown
 * @return
 */
fun markdownToHtmlExtensions(markdown: String): String {
    //h标题生成id
    val headingAnchorExtensions: Set<Extension> = Collections.singleton(HeadingAnchorExtension.create())
    //转换table的HTML
    val tableExtension: List<Extension> = listOf(TablesExtension.create())
    val parser: Parser = Parser.builder()
            .extensions(tableExtension)
            .build()
    val document: Node = parser.parse(markdown)
    val renderer = HtmlRenderer.builder()
            .extensions(headingAnchorExtensions)
            .extensions(tableExtension)
            .attributeProviderFactory { CustomAttributeProvider() }
            .build()
    return renderer.render(document)
}

/**
 * 处理标签的属性
 */
internal class CustomAttributeProvider : AttributeProvider {
    override fun setAttributes(node: Node, tagName: String, attributes: MutableMap<String, String>) {
        //改变a标签的target属性为_blank
        if (node is Link) {
            attributes["target"] = "_blank"
        }
        if (node is TableBlock) {
            attributes["class"] = "ui celled table"
        }
    }
}

/**
 * MD5加密类
 * @param str 要加密的字符串
 * @return    加密后的字符串
 */
fun md5Code(str: String): String? {
    return try {
        val md = MessageDigest.getInstance("MD5")
        md.update(str.toByteArray())
        val byteDigest = md.digest()
        var i: Int
        val buf = StringBuffer("")
        for (offset in byteDigest.indices) {
            i = byteDigest[offset].toInt()
            if (i < 0) i += 256
            if (i < 16) buf.append("0")
            buf.append(Integer.toHexString(i))
        }
        //32位加密
        buf.toString().toUpperCase()
        // 16位的加密
        //return buf.toString().substring(8, 24);
    } catch (e: NoSuchAlgorithmException) {
        e.printStackTrace()
        null
    }
}
